package org.ymh.unix_file_system.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.ymh.unix_file_system.domain.FileSystemError;
import org.ymh.unix_file_system.domain.FreeBlockLinkedList;
import org.ymh.unix_file_system.domain.GlobalVariable;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author lenovo
 * @version 1.0
 * @description: TODO
 * @date 2023/12/17 1:31
 */
@Repository
public class FreeBlockLinkedListOperate extends FreeBlockLinkedList{
    @Autowired
    private JsonDataOperate jsonDataOperate;
    @Autowired
    private BlockOperate blockOperate;
    @Autowired
    private GlobalVariable globalVariable;
    @Autowired
    private FileSystemError error;
    /**
    * @Description 回收盘块(增加一个空闲盘块)
    * @Author  lenovo
    * @Date   2023/12/17 2:12
    * @Param
    * @Return
    * @Exception
    */
    public void addFreeBlock(short[] blockIndex)
    {
        ArrayList<Integer> stack = globalVariable.rootStack.stack;
        for (int i = 0; i < blockIndex.length; i++) {
            blockOperate.blockRecycle(blockIndex[i]);//回收
            if(stack.get(0)>=globalVariable.foundation.stackMaxSize)
            {
                jsonDataOperate.jsonFileStringify(globalVariable.rootStack,new String[]{blockIndex[i]+""});
                stack.clear();
                stack.add(1);
                stack.add((int) blockIndex[i]);
            }
            else if(stack.get(0)>=0)
            {
                stack.add((int) blockIndex[i]);
                stack.set(0,stack.get(0)+1);
            }
        }
    }
    public ArrayList<Integer> allocateBlock(Long B)
    {
        ArrayList<Integer> returnList = new ArrayList<>();
        if(!error.isOutMemory(B,error.OutOfMemoryError))
        {
            int needBlocks = (int) Math.ceil(B*1.0 / 1024);
            while(needBlocks>0)
            {
                returnList.add(allocateABlock());
                needBlocks--;
            }
            return returnList;
        }
        return null;
    }
    /**
    * @Description
    * @Author  lenovo
    * @Date   2023/12/17 14:03
    * @Param
    * @Return
    * @Exception
    */

    private Integer allocateABlock()
    {
        Integer returnVariable=-1;
        ArrayList<Integer> stack = globalVariable.rootStack.stack;
        if(globalVariable.superBlock.blockCountRest==1)
        {
            Integer variable = stack.get(stack.size() - 1);
            stack.remove(stack.size()-1);
            returnVariable= variable;
        }
        else if(globalVariable.superBlock.blockCountRest>1)
        {
            if(stack.get(0)==1)
            {
                Integer variable = stack.get(stack.size() - 1);
                //读入json
                FreeBlockLinkedList list = jsonDataOperate.jsonFileParse(new FreeBlockLinkedList(), variable + "");
                globalVariable.rootStack.stack=list.stack;//
                returnVariable= variable;
            }
            else if(stack.get(0)>1)
            {
                Integer variable = stack.get(stack.size() - 1);
                stack.remove(stack.size()-1);
                stack.set(0,stack.get(0)-1);
                returnVariable= variable;
            }

        }
        else{
            error.isOutMemory(1L,error.OutOfMemoryError);
        }
        if(returnVariable!=-1)
        {
            if(!blockOperate.blockAllocate(returnVariable))
            {
                error.setError(error.BlockOfFreeBlockLinkedListOccupyError);
            }
        }
       return returnVariable;
    }
}
